<?php

/**
 * @category   Ac
 * @package    Application_Model
 * @copyright  Orient Network Ltd
 * @license    Closed
 * @author     John Wilson Lee
 */
class Model_ListingScore extends Ac_Model
{
    protected static $_collection = 'listing_score';
    protected static $_likeScore = 5;
    protected static $_visitScore = 1;
    
    protected static $_scoreReg = array(
    	'visit' => 1,
    	'like' => 5
    );
    
    protected static $_dateLimit = 30;

    /**
     *
     * @var array define the requirements for this model
     */
    protected static $_requirements = array(
    );

    public function __construct($data = array(), $config = array())
	{
        $config['collection'] = 'listing_score';
        parent::__construct($data, $config);
    }

    public function __get($name)
    {
        if ($name == 'object') {
            return Model_Listing::find($this->obj);
        } elseif($name == 'user') {
            return Model_User::find($this->us);
        } else {
            return parent::__get($name);
        }
    }
    
	public static function getLikeNum()
    {
       $map = new MongoCode(
    		"function(){
    			if('us' in this){
    				emit(this.us.toString(), {ct: this.ob_t[0], obj: this.obj});
    			}
    		}"
    	);
    	
    	$reduce = new MongoCode(
    		"function(key, values){
    			var likeArray = new Array();
    			values.forEach(function(v){
    				if(likeArray[v.ct] instanceof Array === false)
    				{
    					likeArray[v.ct] = new Array();
    				}
    				likeArray[v.ct][v.obj] = 0;
    			});
    			values.forEach(function(v){
    				likeArray[v.ct][v.obj] ++;
    			});
    			return {LikeNum: likeArray};
    		}"
    	);
    	
    	$like = new Model_Like();
    	$result = $like->_getMongoDb()->command(array(
	    	"mapreduce" => $like->getCollectionName(), 
		    "map" => $map,
		    "reduce" => $reduce,
    		//"query" => array('c_dt' => array('$gte' => new MongoDate(time() - self::$_dateLimit*24*3600))),
    		"out" => array('inline' => 1)
    	));
    	//dump($result);
    	$result = self::formatMapreduceResult($result['results'], 'LikeNum');
    	//dump($result);			
    	return $result;
	}
    
	
	public static function getVisitNum()
    {
       $map = new MongoCode(
    		"function(){
    			if('us' in this){
    				emit(this.us.toString(), {ct: this.ob_t[0], obj: this.obj});
    			}
    		}"
    	);
    	
    	$reduce = new MongoCode(
    		"function(key, values){
    			var visitArray = new Array();
    			values.forEach(function(v){
    				if(visitArray[v.ct] instanceof Array === false)
    				{
    					visitArray[v.ct] = new Array();
    				}
    				visitArray[v.ct][v.obj] = 0;
    			});
    			values.forEach(function(v){
    				visitArray[v.ct][v.obj] ++;
    			});
    			return {VisitNum: visitArray};
    		}"
    	);
    	
    	$visit = new Model_Visit();
    	$result = $visit->_getMongoDb()->command(array(
	    	"mapreduce" => $visit->getCollectionName(), 
		    "map" => $map,
		    "reduce" => $reduce,
    		//"query" => array('c_dt' => array('$gte' => new MongoDate(time() - self::$_dateLimit*24*3600))),
    		"out" => array('inline' => 1)
    	));
    	//dump($result);
    	$result = self::formatMapreduceResult($result['results'], 'VisitNum');
    	return $result;
	}
	
	/**
	 * 
	 * @return 
	 * array(
	 * 		[uid] => array(
	 * 			[visit/like num] => array(
	 * 				[top category] => array(
	 * 					[listing id] => array(visit/like => num)
	 * 					[listing id] => array(visit/like => num)
	 * 					...
	 * 				)
	 * 			)	
	 * 		)
	 * 
	 * 		...
	 * )
	 */
	private static function formatMapreduceResult($arr, $resultKey = 'likeNum')
	{
		//dump($arr);
		$ret = array();
		if(!empty($arr)){
			foreach($arr as $k => $v){
				if(isset($v['value'][$resultKey])){
					$resultKey_val = $v['value'][$resultKey];
					foreach($resultKey_val as $category => $objInfo){
						foreach($objInfo as $objId => $resultKey_num){
							$resultKey_val[$category][$objId] = array($resultKey => $resultKey_num);
						}
					}				
				}else{
					$resultKey_val = array();
					$resultKey_val[$v['value']['ct']->__toString()] = array($v['value']['obj']->__toString() => array($resultKey => 1));
				}
	
				$ret[$v['_id']] = $resultKey_val;
			}
		}
		
		return $ret;
	}
	
    public static function getCount($id) 
    {

    }

    public static function getScore($id) 
    {

    }
	
    
    /**
     * need to change $gte=>$lte
     * Enter description here ...
     * @param unknown_type $arr
     */
    public static function filterUser($arr)
    {
    	$result = array();
    	foreach ($arr as $key=>$val){
    		if(is_object(Model_User::one(array('_id'=>new MongoId($key), 'emailed'=>'0', 'l_t'=>array('$lte'=>new MongoDate(time()-self::$_dateLimit*24*60*60)))))){
    			$result[$key] = $val;
    		}
    	}
    	//dump($result);
    	return $result;
    }
    
	public static function getTopScoreList($arr)
	{
		//dump($arr);
		$result = array();
		foreach ($arr as $user=>$categorys){
			foreach ($categorys as $listings=>$scorelists){
				foreach ($scorelists as $listing=>$scorelist){
					$score_like = 0;
					$score_visit = 0;
					if(isset($scorelist['LikeNum'])){
						$score_like = $scorelist['LikeNum']*self::$_likeScore;
					}
					if(isset($scorelist['VisitNum'])){
						$score_visit = $scorelist['VisitNum']*self::$_visitScore;
					}
					$score_total = $score_like + $score_visit;
					$result[$user][$listings][$listing] = $score_total;
				}
			}
		}
		
		$top_list = array();
		foreach ($arr as $user=>$categorys){
			foreach ($categorys as $listings=>$scorelists){
				if(count($scorelists) >= 2){
					$top_list[$user][] = array_search(max($scorelists), $scorelists);
					unset($scorelists[array_search(max($scorelists), $scorelists)]);
					$top_list[$user][] = array_search(max($scorelists), $scorelists);
				}else{
					foreach (array_keys($scorelists) as $scorelist){
						$top_list[$user][] = $scorelist;
					}
				}
			}
		}
		return $top_list;
	}

	public static function getRelatedList($arr)
	{
		//dump($arr);
		$result = array();
		foreach ($arr as $user=>$listings){
			foreach ($listings as $listing){
				if(is_object(Model_Listing::find(new MongoId($listing)))){
					foreach (Model_Listing::find(new MongoId($listing))->findRelated(3, Model_Listing::RELATED_TOP_CATEGORY) as $val){
						if(is_object($val)){
							$result[$user][] = $val;
						}
					}
				}
			}
		}
//		foreach ($result as $val)
//		{
//			foreach ($val as $v)
//			{
//				echo $v->title_sc.'[1]<br>';
//			}
//			echo '<br>---------------<br>';
//		}

		return $result;
	}
}
